/////////////////////////////////////////////////////////////////////////
// 语义分析
// 对函数调用做引用消解（Refrence Resolving），也就是找到函数的声明。

use std::cell::RefCell;
use super::nast::Prog;
use super::nast::FunctionCall;
use super::nast::FunctionDecl;
use super::nast::FunctionBody;
use super::nast::Statements;

/**
 * 遍历AST。如果发现函数调用，就去找它的定义。
 */
pub struct RefResolver  {
}

impl RefResolver{
	//开始语义消解
	pub fn visit_prog(prog : &mut Prog) -> &mut Prog {
		let x = (*prog).clone();
		let mut stmts_new:Vec<Statements> = Vec::new();

		for stmt in prog.stmts.iter_mut() {
			//根据stmt的类型，进行不同的处理
			match stmt {
				Statements::FunctionCall(v) => {
					v.definition_index = RefResolver::resolve_function_call(x.clone(), v);
					if v.definition_index<0 {
						println!("{} function definition not resolved!",  v.name);
					}
					stmts_new.push(Statements::FunctionCall(v.clone()));
				},
				Statements::FunctionDecl(v) => {
					v.body = RefResolver::visit_function_decl(&x, v.clone());
					if v.body.is_none() {
						println!("{} function decl not resolved!",  v.name);
					}
					stmts_new.push(Statements::FunctionDecl(v.clone()));
				},
			}
		}

		prog.stmts = stmts_new;
		return prog;
	}

	//对于一个函数调用，查找函数声明，进行引用消解
	fn resolve_function_call(prog: Prog, function_call: &FunctionCall) -> i32 {
		let function_decl_index = RefResolver::find_function_decl(prog, &function_call.name);

		if function_decl_index>=0{
			//找到非系统内置函数
			println!("{}{}", "resolveFunctionCall successed: " , function_call.name);
			return function_decl_index;
		} else {
			if function_call.name.eq("nl.println") {
				//找到系统函数
				println!("{}{}", "resolveSysCall successed: " , function_call.name);
			}
			else {
				//除系统内置函数外，找不到引用，要报错
				println!("{}{}", "Error: cannot find definition of function " , function_call.name);
			}
			return -1;
		}
	}

	//在全部stmts中，根据名称查找函数声明
	fn find_function_decl(prog: Prog, name:&String) -> i32 {
		let mut i=0;
		while i < prog.stmts.len() {
			match &prog.stmts[i] {
				Statements::FunctionCall(_) => {
					i+=1;
					continue;
				},
				Statements::FunctionDecl(v) => {
					if v.name.eq(name) {
						return i as i32;
					}
					i+=1;
				},
			};
		}

		return -1;
	}

	//通过函数声明，访问函数体
	//这里要看子类如何继承
	fn visit_function_decl(prog:&Prog, function_decl: FunctionDecl) -> Option<RefCell<FunctionBody>>{
		return RefResolver::visit_function_body(prog, function_decl.body);
	}

	//对函数体中的每一个函数调用，都进行引用消解
	fn visit_function_body(prog: &Prog, function_body: Option<RefCell<FunctionBody>>) -> Option<RefCell<FunctionBody>>{
		if function_body.is_none() {
			return None;
		}

		let x = function_body.clone().unwrap();
		let mut stmts_new:Vec<FunctionCall> = Vec::new();

		for stmt in x.borrow_mut().stmts.iter_mut() {
			let mut stmt_new = stmt.clone();
			stmt_new.definition_index = RefResolver::resolve_function_call(prog.clone(), stmt);
			stmts_new.push(stmt_new);
		}

		x.borrow_mut().stmts = stmts_new;
		return Some(x);
	}
}
